# -*- coding: utf-8 -*-

"""
@Time       :   2024/05/22
@Author     :   Li Kuangyuan, Yi Junquan
@Version    :   1.0
@Contact    :   1767958859@qq.com
@Software   :   VsCode
"""

from collections import namedtuple
from enum import Enum

class Dataset(Enum):
    # 四个数据集的各种属性
    # 数据集名称, 准标识符属性index列表, 准标识符属性类型, 目标变量
    MGM = {
        'dataset': 'mgm', 
        'quasi_index_list': [1, 2, 3, 4, 5], 
        'category_flag_list': [True, False, True, True, True], 
        'max_numeric': {"age": 50.5},
        'target_var': 'severity'
    }
    ADULT = {
        'dataset': 'adult', 
        'quasi_index_list': [1, 2, 3, 4, 5, 6, 7, 8], 
        'category_flag_list': [True, False, True, True, True, True, True, True], 
        'max_numeric': {"age": 50.5},
        'target_var': 'salary-class'
    }

    def __str__(self):
        return self.value['dataset']

    def __eq__(self, other):
        return str(other) == self.value['dataset']

class KAnonymity(Enum):
    MONDRIAN = 'mondrian'
    OKA = 'oka'
    TDG = 'tdg'
    # 匿名化方法
    def __str__(self):
        return self.value

    def __eq__(self, other):
        return str(other) == self.value

class Model(Enum):
    LR = 'lr' # 线性回归
    NB = 'nb'
    KNN = 'knn'
    SVM = 'svm'
    GBT = 'gbt'

    def __str__(self):
        return self.value

    def __eq__(self, other):
        return str(other) == self.value

class NRange(object):
    # NumericalRange
    def __init__(self, sort_value, support):
        """泛化层次结构, Taxonomy Tree
        存储数据类型的属性
        self.sort_value: 排序后的值
        self.value: 节点值范围, (min_value, max_value)
        self.support: 
        self.range: 最大最小值的差值
        self.dict: value到index的映射关系
        """
        self.sort_value = list(sort_value)
        self.value = str(sort_value[0]) + ',' + str(sort_value[-1])
        self.support = support.copy()
        self.range = float(sort_value[-1]) - float(sort_value[0])
        self.dict = {}
        for i, v in enumerate(sort_value):
            self.dict[v] = i
        
    def __len__(self):
        # 放回最大最小值的差值(数值范围的长度)
        return self.range

class GTree(object):
    # GeneralizationTree
    def __init__(self, value=None, parent=None, isleaf=False):
        """泛化层次结构, Taxonomy Tree
        存储非数据类型的属性
        self.value: 节点值
        self.level: 层次, (根节点为0)
        self.leaf_num: 叶节点数
        self.parent: 祖先节点列表
        self.child: 子节点列表
        self.cover: 当前节点的所有后代节点, 字典, key=node.value, value=node
        """
        # 初始化节点属性
        self.value = ''
        self.level = 0
        self.leaf_num = 0
        self.parent = []
        self.child = []
        self.cover = {}
        self.init_values(value, parent, isleaf)

    def init_values(self, value, parent, flag):
        if value is not None:
            self.value = value
            self.cover[value] = self
        if parent is not None:  
            # 父节点 = 父节点 + 父节点的父节点列表
            self.parent = parent.parent[:]
            self.parent.insert(0, parent)   
            # 遍历父节点, 更新父节点属性
            for t in self.parent:   
                # 更新所有父节点的cover属性    
                t.cover[self.value] = self
                 # 若是叶子节点，更新祖先节点的leaf_num属性
                if flag:
                    t.leaf_num += 1
            # 当前节点深度 = 父节点深度 + 1
            self.level = parent.level + 1  
            # 更新直接父节点的子节点列表
            self.parent[0].child.append(self)   
            

    def node(self, value):
        # 根据value搜索node(仅搜索自己和子节点的属性)
        return self.cover.get(value)

    def __len__(self):
        # 返回叶子节点数目
        return self.leaf_num

